#!/usr/bin/env python
# encoding: utf-8

import sys
import os
import time
from pyfann import libfann

def main():
	connection_rate 				= 1
	learning_rate 					= 0.7
	
	num_output 						= 1
	
	max_iterations 					= 5000
	iterations_between_reports 		= 100
	
	parameters = [{"title": "Abalone", "train_file": "abalone_train.data", "test_file": "abalone_test.data", "inputs": 8, "hidden": [8, 16, 32, 64], "desired_error": .01},
				  {"title": "Chess", "train_file": "chess_train.data", "test_file": "chess_test.data", "inputs": 6, "hidden": [6, 12, 24, 48], "desired_error": .01},
				  {"title": "Wine", "train_file": "wine_train.data", "test_file": "wine_test.data", "inputs": 11, "hidden": [11, 22, 44, 88], "desired_error": .001}]
	
	for p in parameters:
		
		print "================= %s =================" % p["title"]
		
		for h in p["hidden"]:
			print "Hidden neurons: %s" % h
			
			print "\nTraining..."
			# initialize network
			ann = libfann.neural_net()
			ann.create_sparse_array(connection_rate, (p["inputs"], h, num_output))
			ann.set_learning_rate(learning_rate)
			
			# activation functions
			ann.set_activation_function_hidden(libfann.SIGMOID)
			ann.set_activation_function_output(libfann.SIGMOID)
			
			# read training data
			trainData = libfann.training_data()
			trainData.read_train_from_file("../processed_data/%s" % p["train_file"])
			
			# scale data
			trainData.scale_train_data(0, 1)
			
			start = time.time()
			
			# train network
			ann.train_on_data(trainData, max_iterations, iterations_between_reports, p["desired_error"])
			
			end = time.time()
			
			trainTime = (end - start) * 1000
			
			print "\nTesting...",
			
			# test
			testData = libfann.training_data()
			testData.read_train_from_file("../processed_data/%s" % p["test_file"])
			
			ann.reset_MSE()
			
			start = time.time()
			
			testMSE = ann.test_data(testData)
			testBitFail = ann.get_bit_fail()
			
			end = time.time()
			
			testTime = (end - start) * 1000
			
			print " train time: %s, test time: %s, mse: %s, bit fail: %s\n" % (trainTime, testTime, testMSE, testBitFail)
			


if __name__ == '__main__':
	main()

